package com.huajx.mina.test;

import com.huajx.core.util.MessageKit;
import com.huajx.tb.codec.NengLongDecoder;
import com.huajx.tb.codec.NengLongEncoder;
import com.huajx.util.CharUtil;
import com.huajx.util.StrUtil;
import com.huajx.util.date.DatePattern;
import com.huajx.util.date.DateUtil;
import com.huajx.util.io.FileUtil;
import org.apache.mina.core.future.ConnectFuture;
import org.apache.mina.core.service.IoConnector;
import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.ProtocolCodecFactory;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filter.codec.ProtocolDecoder;
import org.apache.mina.filter.codec.ProtocolEncoder;
import org.apache.mina.transport.socket.nio.NioSocketConnector;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.UnsupportedEncodingException;
import java.net.InetSocketAddress;
import java.nio.charset.Charset;
import java.util.Date;

/**
 * @program: di-parent
 * @description:
 * @author: lisa 叶新华
 * @create: 2019-10-14 10:15
 */
public class TianboTcpClient extends IoHandlerAdapter {
    private static final Logger logger = LoggerFactory.getLogger(TianboTcpClient.class);
    private IoConnector connector;
    private static IoSession session;
    //        private final static String IP = "106.225.144.98";
//    private final static int PORT = 9230;
    private final static String IP = "127.0.0.1";
    private final static int PORT = 10041;

    public static void main(String[] args) throws InterruptedException, UnsupportedEncodingException {
        TianboTcpClient client = new TianboTcpClient();
        //弋阳县方志敏中学 电话请求
        String command = "TPJ000103611000000000000010038053047220073          19092519082100000B19970309418     25";

        String schoolId = "361102030";
        String cardId = "12345678910";

        String command2 = "TPJ00070361100000         0016012568764530          AF";

//        client.sent(command);
        client.sent(command2);
//        Thread thread2 = new Thread(() -> {
//            client.sent(command2);
//            client.sleep(100);
//        });
//        thread2.start();

//        for (int i = 0; i < 1; i++) {
//            logger.info("线程{}", i);
//            Thread thread = new Thread(() -> {
//                for (int j = 0; j < 1; j++) {
//                    logger.info("传送数据{}", j);
//                    client.sent(client.sentAttandance(schoolId, cardId, j));
//                }
//                try {
//                    Thread.sleep(100);
//                } catch (InterruptedException e) {
//                    e.printStackTrace();
//                }
//            });
//            thread.start();
//        }

        //弋阳县方志敏中学 电话请求
//        command="TPJ"+"0001"+"0"+"361100000000000001"+"0016"+"01"+"3047220073          9D";
//        client.sent(command);

//        client.sleep(1000L);
//        session.closeNow();
    }

    private void sleep(long millis) {
        try {
            Thread.sleep(millis);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    private String sentAttandance(String schoolId, String cardId, int i) {
        StringBuilder sb = new StringBuilder();
        String deviceId = StrUtil.fillAfter(schoolId, CharUtil.SPACE, 18);
        cardId = StrUtil.fillAfter(cardId, CharUtil.SPACE, 20);

        int count = 7;
        int len = 39 * count + 4;
        String lenHex = Integer.toHexString(len);

        lenHex = StrUtil.fillBefore(lenHex, '0', 4);

        String countStr = StrUtil.fillBefore(count + "", '0', 2);

        Date date = DateUtil.offsetHour(new Date(), 15);

        date = DateUtil.offsetDay(date, i);

        sb.append("TPJ").append("0001").append("1").append(deviceId).append(lenHex).append("08").append(countStr);
        for (int j = 0; j < count; j++) {
            date = DateUtil.offsetMinute(date, j * 10);
            String dateStr = DateUtil.format(date, "yyMMddHHmmss");
            sb.append(cardId).append(dateStr).append(j % 2).append("0E").append("2010");
        }
        sb.append("0E");
        return sb.toString();
    }

    private String gbk2utf8(byte[] bytes) throws UnsupportedEncodingException {
//        String src = new String(bytes, "gb2312");
        return new String(convertEncoding_ByteArr(bytes, "gb2312", "utf-8"));
    }

    public static byte[] convertEncoding_ByteArr(byte[] src, String srcCharset, String destCharet)
            throws UnsupportedEncodingException {
        String s = new String(src, srcCharset);
        return s.getBytes(destCharet);
    }

    public void sent(String commond) {
        session.write(commond.getBytes());
    }

    public TianboTcpClient() {
        connector = new NioSocketConnector();
        connector.getFilterChain().addLast("codec",
                new ProtocolCodecFilter(new ProtocolCodecFactory() {
                    @Override
                    public ProtocolEncoder getEncoder(IoSession session) throws Exception {
                        return new NengLongEncoder();
                    }

                    @Override
                    public ProtocolDecoder getDecoder(IoSession session) throws Exception {
                        return new NengLongDecoder();
                    }
                })
        );
        connector.setHandler(this);
        ConnectFuture connFuture = connector.connect(new InetSocketAddress(IP, PORT));
        connFuture.awaitUninterruptibly();
        session = connFuture.getSession();
    }

    long startTime = 0;
    long endTime = 0;

    @Override
    public void messageReceived(IoSession iosession, Object message) throws Exception {
        super.messageReceived(iosession, message);
        if (message instanceof byte[]) {
            endTime = System.currentTimeMillis();
            logger.info("接收时间：{}, 接收数据(byte[])：{}    ", endTime - startTime, new String((byte[]) message));

//            String ll = "测试1                                                       ";
//            String ll2 = new String(convertEncoding_ByteArr(ll.getBytes(), "utf-8", "gbk"));
//            logger.info("{},{}", ll2.length(), ll2);
//
//            FileUtil.writeBytes(convertEncoding_ByteArr(ll.getBytes(), "utf-8", "gbk"), "abc.json");
//            FileUtil.writeBytes(convertEncoding_ByteArr((byte[]) message, "gb2312", "utf-8"), "abc.json");
//            logger.info("转换数据(byte[]) gbk ：{}", gbk2utf8((byte[]) message));
//            logger.info("接收数据: {}", MessageKit.bytesToString((byte[]) message));
        }
    }

    @Override
    public void exceptionCaught(IoSession session, Throwable cause) throws Exception {
        super.exceptionCaught(session, cause);
        logger.info("客户端异常");
    }

    @Override
    public void messageSent(IoSession iosession, Object message) throws Exception {
        if (message instanceof byte[]) {
            startTime = System.currentTimeMillis();
            logger.info("发送时间： {}, 发送命令: {} ", startTime, MessageKit.bytesToString((byte[]) message));
        }
        super.messageSent(iosession, message);
    }

    @Override
    public void sessionClosed(IoSession iosession) throws Exception {
        logger.info("客户端会话关闭");
        super.sessionClosed(iosession);
        connector.dispose();
    }

    @Override
    public void sessionCreated(IoSession iosession) throws Exception {
        logger.info("客户端会话创建");
        super.sessionCreated(iosession);
    }

    @Override
    public void sessionIdle(IoSession iosession, IdleStatus idlestatus)
            throws Exception {
        logger.info("客户端会话休眠");
        super.sessionIdle(iosession, idlestatus);
    }

    @Override
    public void sessionOpened(IoSession iosession) throws Exception {
        logger.info("客户端会话打开");
        super.sessionOpened(iosession);
    }
}
